import 'package:drive/drive.dart';
import 'package:drive/src/utils/ddialog/view.dart';
import 'package:flutter/material.dart';

class BubbleItem {
  late final String logo;
  late final String text;
  final _key = GlobalKey();
  final Widget? child;
  final int? tipsNum;

  BubbleItem({
    this.logo = "",
    this.tipsNum ,
    this.text = "",
    this.child,
  });
}

class BubbleButton extends StatefulWidget {
  late final List<BubbleItem> bubbleItem;
  late final TextStyle style;
  late final Color selectColor;
  late final int selectIndex;
  late final EdgeInsets padding;
  late final EdgeInsets itemPadding;
  late final double spec;
  late final void Function(int) onChangeListener;
  late final double iconSize;

  BubbleButton(
      {Key? key,
      required this.onChangeListener,
      required this.style,
      this.padding = EdgeInsets.zero,
      required this.spec,
      this.itemPadding = EdgeInsets.zero,
      required this.selectColor,
      this.selectIndex = 0,
      this.iconSize = 15,
      required this.bubbleItem})
      : super(key: key);

  @override
  State<BubbleButton> createState() => _BubbleButtonState();
}

class _BubbleButtonState extends State<BubbleButton> {
  final GlobalKey globalKey = GlobalKey();

  int selectIndex = 0;

  initState() {
    super.initState();
    selectIndex = widget.selectIndex;
  }

  @override
  void didUpdateWidget(covariant BubbleButton oldWidget) {
    super.didUpdateWidget(oldWidget);
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onClick,
      key: globalKey,
      behavior: HitTestBehavior.opaque,
      child: Container(
        alignment: Alignment.centerLeft,
        padding: widget.padding,
        child: Row(
          children: [
            Text(
              widget.bubbleItem[selectIndex].text,
              style: widget.style,
            ),
            SizedBox(
              width: widget.spec,
            ),
            Icon(
              Icons.arrow_drop_down_rounded,
              color: widget.style.color,
              size: widget.iconSize,
            ),
          ],
        ),
      ),
    );
  }

  void onClick() async {
    final renderBox = globalKey.currentContext?.findRenderObject() as RenderBox;
    final size = renderBox.size;
    final offset = renderBox.localToGlobal(Offset(0, 0));

    final result = await DDialogUtils.showAlphaDialog(
        context,
        BubbleItemPop(
            parentOffset: offset,
            parentSize: size,
            itemPadding: widget.itemPadding,
            selectIndex: selectIndex,
            selectColor: widget.selectColor,
            style: widget.style,
            bubbleItem: widget.bubbleItem));
    if (result != null) {
      if (selectIndex == result) return;
      selectIndex = result;
      widget.onChangeListener.call(selectIndex);
      setState(() {});
    }
  }
}

class BubbleItemPop extends StatefulWidget {
  final Offset parentOffset;
  late final Size parentSize;
  late final List<BubbleItem> bubbleItem;
  late final int selectIndex;
  late final Color selectColor;
  late final TextStyle style;
  late final Color lineColor;
  late final EdgeInsets itemPadding;
  late final Color backgroundColor;

  BubbleItemPop(
      {Key? key,
      required this.parentOffset,
      required this.style,
      this.backgroundColor = Colors.white,
      this.lineColor = const Color(0x0f000000),
      required this.selectIndex,
      required this.selectColor,
      this.itemPadding = EdgeInsets.zero,
      required this.parentSize,
      required this.bubbleItem})
      : super(key: key);

  @override
  State<BubbleItemPop> createState() => _BubbleItemPopState();
}

class _BubbleItemPopState extends State<BubbleItemPop> {
  final key = GlobalKey();
  double dx = 0;
  double tx = 0;
  double thisWidth = 0;
  double? width = null;

  @override
  void initState() {
    super.initState();
    dx = 0;
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      final width = key.currentContext!.size!.width;
      thisWidth = width - 24;
      this.width = width+5;
      dx = widget.parentOffset.dx - (width - widget.parentSize.width) / 2;
      final screenWidth = MediaQuery.of(context).size.width-10;

      if (width + dx > screenWidth) {
        dx = screenWidth - width - 3;
      }
      tx = widget.parentOffset.dx - dx + widget.parentSize.width / 2;
      setState(() {});

      Future.delayed(Duration(milliseconds: 100)).then((value) {

        final width1 = key.currentContext!.size!.width;
      });

    });
  }

  @override
  Widget build(BuildContext context) {
    final children = <Widget>[];

    for (var index = 0; index < widget.bubbleItem.length; index++) {
      final item = widget.bubbleItem[index];

      children.add(GestureDetector(
        onTap: () {
          Navigator.of(context).pop(index);
        },
        behavior: HitTestBehavior.opaque,
        child: Container(
          height: 40,
          width: width,
          // decoration: BoxDecoration(border: Border.all(color: Colors.black.withOpacity(0.04))),
          child: Stack(
            alignment: Alignment.centerLeft,
            fit: StackFit.loose,
            children: [

              Container(
                padding: EdgeInsets.only(left: widget.itemPadding.left+(item.logo.isNotEmpty ? 36 : 0)
                ,right: widget.itemPadding.right),
                child: Text(
                  item.text,
                  key: item._key,
                  maxLines: 1,
                  style: index == widget.selectIndex
                      ? widget.style.copyWith(color: widget.selectColor)
                      : widget.style,
                ),
              ),
              if (item.tipsNum!=null&&item.tipsNum!=0 && item._key.currentContext != null)
                LayoutBuilder(builder: (ctx, sin) {
                  final renderBox=((item._key.currentContext as Element?)!.findRenderObject() as RenderBox).size;
                  String t=item.tipsNum!>99?"99+":item.tipsNum!.toString();
                  double s=widget.itemPadding.left+35-t.length*4;

                  double left=(item.logo.isNotEmpty ? s:0)+renderBox.width;
                  return Container(
                    margin: EdgeInsets.only(left: left,bottom: 16),
                    height: 14,
                    padding: EdgeInsets.only(left: 5,right: 5,top: 2),

                    decoration: BoxDecoration(color: Color(0xffFB0469),borderRadius: BorderRadius.circular(8)),
                    child: Text(
                      t,
                      maxLines: 1,
                      style: resTextStyle.copyWith(
                        height: 1.0,
                          fontSize: 10, color: Colors.white),
                    ),
                  );
                }),

              if (item.logo.isNotEmpty) Padding(
                padding: EdgeInsets.only(left: widget.itemPadding.left),
                child: Image.asset(item.logo),
              ),
            ],
          ),
        ),
      ));

      if (width != null && index < widget.bubbleItem.length - 1)
        children.add(LayoutBuilder(builder: (context, con) {
          return Container(
            margin: EdgeInsets.only(
                left: item.logo.isNotEmpty ? 36 + widget.itemPadding.left : 8,
                right: 8),
            height: 1,
            // height: 1.dp,
            // width: con.maxWidth,
            color: widget.lineColor,
            // margin: EdgeInsets.only(left: 12.dp, right: 12.dp),
          );
        }));
    }

    return GestureDetector(
      onTap: () => Navigator.of(context).pop(),
      child: Container(
          alignment: Alignment.topLeft,
          padding: EdgeInsets.only(
              top: widget.parentOffset.dy + widget.parentSize.height,
              bottom: 4,
              left: dx),
          child: GestureDetector(
              onTap: () {},
              behavior: HitTestBehavior.opaque,
              child: Container(
                key: key,
                width: width,
                child: Bubble(
                    dx: tx,
                    color: widget.backgroundColor,
                    child: Padding(
                      padding: EdgeInsets.only(
                          top: widget.itemPadding.top,
                          bottom: widget.itemPadding.bottom),
                      child: Column(
                        mainAxisSize: MainAxisSize.min,
                        children: children,
                      ),
                    )),
              ))),
    );
  }
}

class Bubble extends StatelessWidget {
  late final Widget child;
  late final Color color;
  final double? dx;

  Bubble({Key? key, this.dx, this.color = Colors.white, required this.child})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      painter: BubblePainter(color, dx),
      // size: Size(88.dp, 177.dp),
      child: Padding(
        padding: EdgeInsets.only(top: 6),
        child: child,
      ),
    );
  }

  void onTap() {}
}

class BubblePainter extends CustomPainter {
  late Color color; //填充颜色
  late Paint _paint; //画笔
  late Path _path; //绘制路径
  late Paint _blurPaint; //画笔
  double? dx;

  BubblePainter(this.color, this.dx) {
    _paint = Paint()
      ..strokeWidth = 1.0 //线宽
      ..color = color
      ..isAntiAlias = true;
    _blurPaint = Paint()
      ..color = Colors.black.withOpacity(0.1)
      ..maskFilter = MaskFilter.blur(BlurStyle.normal, 16);

    _path = Path();
  }

  @override
  void paint(Canvas canvas, Size size) {
    final startX = dx ?? size.width / 2;
    final ex = 6.0;
    _path.moveTo(startX, 0);
    _path.lineTo(startX + ex, ex);
    _path.lineTo(size.width - 4, ex);
    _path.quadraticBezierTo(size.width, ex, size.width, 10);
    _path.lineTo(size.width, size.height - 4);
    _path.quadraticBezierTo(
        size.width, size.height, size.width - 4, size.height);
    _path.lineTo(4, size.height);
    _path.quadraticBezierTo(0, size.height, 0, size.height - 4);
    _path.lineTo(0, 10);
    _path.quadraticBezierTo(0, ex, 4, ex);
    _path.lineTo(startX - ex, ex);

    canvas.drawPath(_path, _blurPaint);
    canvas.drawPath(_path, _paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}
